﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Domain.Core.Specification;
using System.Linq.Expressions;
using Domain.Core.Extensions;

namespace Domain.Core
{
    public interface IRepository<TEntity>
           where TEntity : class
    {
        /// <summary>
        /// 添加实体并提交到数据服务器
        /// </summary>
        /// <param name="item">Item to add to repository</param>
        void Add(TEntity item);

        /// <summary>
        /// 移除实体并提交到数据服务器
        /// 如果表存在约束，需要先删除子表信息
        /// </summary>
        /// <param name="item">Item to delete</param>
        void Remove(TEntity item);

        /// <summary>
        /// 修改实体并提交到数据服务器
        /// </summary>
        /// <param name="item"></param>
        void Modify(TEntity item);

        /// <summary>
        /// 修改实体指定字段
        /// </summary>
        /// <param name="entity"></param>
        void Modify(Expression<Action<TEntity>> entity);

        /// <summary>
        /// 通过指定规约，得到实体对象
        /// </summary>
        /// <param name="specification"></param>
        /// <returns></returns>
        TEntity GetEntity(ISpecification<TEntity> specification);
        /// <summary>
        /// 通过指定lambda，得到实体对象
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        TEntity GetEntity(Expression<Func<TEntity, bool>> predicate);
        /// <summary>
        /// Get all elements of type {T} in repository
        /// </summary>
        /// <returns>List of selected elements</returns>
        IQueryable<TEntity> GetEntities();

        /// <summary>
        /// Get all elements of type {T} that matching a
        /// Specification <paramref name="specification"/>
        /// </summary>
        /// <param name="specification">Specification that result meet</param>
        /// <returns></returns>
        IQueryable<TEntity> GetEntities(ISpecification<TEntity> specification);

        /// <summary>
        /// Get all elements of type {T} that matching a Specification in repository
        /// </summary>
        /// <param name="specification"></param>
        /// <param name="pageIndex"></param>
        /// <param name="pageCount"></param>
        /// <param name="orde"></param>
        /// <returns></returns>
        IEnumerable<TEntity> GetEntities(ISpecification<TEntity> specification, int pageIndex, int pageCount, Action<Orderable<TEntity>> orde);

        /// <summary>
        /// Get all elements of type {T} in repository
        /// </summary>
        /// <param name="pageIndex">Page index</param>
        /// <param name="pageCount">Number of elements in each page</param>
        /// <param name="orderByExpression">Order by expression for this query</param>
        /// <param name="ascending">Specify if order is ascending</param>
        /// <returns>List of selected elements</returns>
        IEnumerable<TEntity> GetEntities(int pageIndex, int pageCount, Action<Orderable<TEntity>> order);

        /// <summary>
        /// 过滤记录，通用表达式树
        /// </summary>
        /// <param name="predicate"></param>
        /// <returns></returns>
        IQueryable<TEntity> GetEntities(Expression<Func<TEntity, bool>> predicate);
    }
}
